package src.controller;

import src.driver.PlayerObjectData;
import src.event.EventHandler;
import src.model.gameWorld.Position;
import src.model.gameWorld.ModelEventHandler;
import src.model.gameObject.GameObjectEventHandler;
import src.model.gameObject.ability.AbilityReturnResult;
import src.event.events.SelectNextUnit;
import src.event.events.SelectNextStructure;
import src.event.events.NextPlayer;
import src.event.events.CursorChangeEvent;
import src.view.ViewEventHandler;

public class GameController{
	private PlayerKeyMap[] pkm;
	private int currentPlayer;

	private String commandInTheMiddleOfBeingPerformed;
	private boolean inTheMiddleOfPerformingACommand;
	private boolean freeRangeMode;

	private Position cursorPos;

	public GameController(PlayerObjectData[] pods){
		currentPlayer = 0;
		pkm = new PlayerKeyMap[pods.length];
		for(int c1=0; c1<pods.length; c1++){
			pkm[c1] = new PlayerKeyMap(pods[c1].getKeyMapPath());
			pkm[c1].saveKeyMap();
		}

		commandInTheMiddleOfBeingPerformed = "";
		inTheMiddleOfPerformingACommand = false;
		freeRangeMode = false;
		cursorPos = new Position(0, 0);
	}

	public void updateCursor(Position p)
	{
		cursorPos = p;
	}

	public void keyTyped(int key){
		String command = pkm[currentPlayer].translateKey(key);

		if(command == null)
			return;

		if(command.equals("USEACTION1")){
			useAction(1);
		}
	      	if(command.equals("USEACTION2")){
			useAction(2);
		}
		if(command.equals("USEACTION3")){
			useAction(3);
		}
		if(command.equals("USEACTION4")){
			useAction(4);
		}
		if(command.equals("USEACTION5")){
			useAction(5);
		}
		if(command.equals("USEACTION6")){
			useAction(6);
		}
		if(command.equals("USEACTION7")){
			useAction(7);
		}
		if(command.equals("USEACTION8")){
			useAction(8);
		}
		if(command.equals("USEACTION9")){
			useAction(9);
		}

		if(command.equals("MOVEN")){
			useMove(Direction.N);
		}
		if(command.equals("MOVENE")){
			useMove(Direction.NE);
		}
		if(command.equals("MOVEE")){
			useMove(Direction.E);
		}
		if(command.equals("MOVESE")){
			useMove(Direction.SE);
		}
		if(command.equals("MOVES")){
			useMove(Direction.S);
		}
		if(command.equals("MOVESW")){
			useMove(Direction.SW);
		}
		if(command.equals("MOVEW")){
			useMove(Direction.W);
		}
		if(command.equals("MOVENW")){
			useMove(Direction.NW);
		}

		if(command.equals("CLEARQUEUE")){
			GameObjectEventHandler.clearQueue();
		}

		if(command.equals("SELECTNEXTUNIT")){
			ModelEventHandler.fireEvent(new SelectNextUnit());
		}
		if(command.equals("SELECTNEXTSTRUCTURE")){
			ModelEventHandler.fireEvent(new SelectNextStructure());
		}
		if(command.equals("NEWTURN")){
			ModelEventHandler.fireEvent(new NextPlayer());
		}

		if(command.equals("FREERANGE")){
			freeRangeMode = !freeRangeMode;
		}

		if(command.equals("STOPCOMMAND")){
			inTheMiddleOfPerformingACommand = false;
			freeRangeMode = false;
		}


	}

	public void mapLeftMouseButtonClicked(int tileX, int tileY){

	}

	public void mapRightMouseButtonClicked(int tileX, int tileY){

	}

	public void unitOverviewLeftMouseButtonClicked(int x, int y){
	}

	public void technologyOverviewLeftMouseButtonClicked(int techID, int y){
	}

	public void structureOverviewLeftMouseButtonClicked(int x, int y){
	}

	public void useMove(Direction dir){
		if(!cursorPos.incX(dir.xChange()))
			return;
		if(!cursorPos.incY(dir.yChange()))
			return;

		if(freeRangeMode || inTheMiddleOfPerformingACommand){
			ViewEventHandler.fireEvent(new CursorChangeEvent(cursorPos.X(), cursorPos.Y()));
			return;
		}

		//Else we want to move the selected unit
		GameObjectEventHandler.useMoveAbility(cursorPos);
	}

	public void useAction(int actionNum){
		if(inTheMiddleOfPerformingACommand){
			if(!commandInTheMiddleOfBeingPerformed.equals("USEACTION" + actionNum))
				return;

			GameObjectEventHandler.useAbility(actionNum, cursorPos);

			inTheMiddleOfPerformingACommand = false;
		} else{
			if(GameObjectEventHandler.useAbility(actionNum) == AbilityReturnResult.NEEDSMOREINFORMATION){
				inTheMiddleOfPerformingACommand = true;
				commandInTheMiddleOfBeingPerformed = "USEACTION" + actionNum;
			}
		}
	}

}